package cmd

import (
	"os/exec"
	"bytes"
	"aDeploy/logger"
	"fmt"
	"regexp"
	"io/ioutil"
	"os"
)

type CmdConfig struct {
	Home string
	//Docker镜像地址
	DockerAddress string
}

var DefaultConfig = CmdConfig{
	Home: "~/aDeploy",
	DockerAddress: "docker.lghdg.com",
}

//定义一个部署任务
type Task struct {
	//git仓库地址
	GitAddress string
	//部署的服务器地址
	ServerAddress string
	//部署的服务器工作目录
	ServerWorkDir string
	//是否第一次执行
	IsInit bool
}

func path(gitaddress string) string {
	reg := regexp.MustCompile(`/(.+)\.git`)
	str := reg.FindString(gitaddress)
	return str[1:len(str)-4]
}

//执行Git
func (task *Task) GitPull() error{
	logger.Debug(fmt.Sprintf("从服务器 %s 拉起代码到 %s", task.GitAddress, DefaultConfig.Home))
	s := "cd %s && git %s"
	var err error = nil
	if task.IsInit {
		str, err := Shell(fmt.Sprintf(s, DefaultConfig.Home, "clone " + task.GitAddress))
		logger.Debug(str)
		if err == nil {
			task.IsInit = false
		}
	}else{
		str, e := Shell(fmt.Sprintf(s, DefaultConfig.Home, " -C " + path(task.GitAddress) + " pull"))
		logger.Debug(str)
		err = e
	}
	if err != nil{
		logger.Debug(fmt.Sprintf("从服务器 %s 拉起代码到 %s, 发生错误：%s", task.GitAddress, DefaultConfig.Home, err))
	}
	return err
}

//构建镜像
func (task *Task) DockerBuild() error {
	logger.Debug("正在构建镜像....")
	gitname := path(task.GitAddress)
	tag := fmt.Sprintf("%s/%s", DefaultConfig.DockerAddress, gitname)
	str, err := Shell(fmt.Sprintf("cd %s/%s && sudo docker build -t %s .", DefaultConfig.Home,gitname,tag))
	logger.Debug(str)
	if err != nil { return err }
	str, err = Shell(fmt.Sprintf("sudo docker push %s", tag))
	logger.Debug(str)
	return err
}

//运行容器
func (task *Task) DockerRun(args string) error {
	ip, err := Shell(`/sbin/ifconfig en0 | grep -E 'inet ' |  awk '{print $2}'`)
	if err != nil { return err}
	gitname := path(task.GitAddress)
	dockerImage := fmt.Sprintf("%s/%s", DefaultConfig.DockerAddress, gitname)
	var command  = "docker run -rt " + args + " " + dockerImage
	if "localhost" != task.ServerAddress &&
		"127.0.0.1" != task.ServerAddress &&
		 ip != task.ServerAddress {
		 	hosts := "[server]\n" + task.ServerAddress
		 	hostsFile := fmt.Sprintf("%s/%s/%s", DefaultConfig.Home,gitname,"hosts")
		 	if checkFileIsExist(hostsFile) {
		 		_, err = Shell("rm -r " + hostsFile)
				if err != nil { return err }
			}
		 	err = ioutil.WriteFile(hostsFile, []byte(hosts), 0666)
			if err != nil { return err }
		 	command = "ansible server -i " + hostsFile + " -m command -a \"" + command  +"\""
		 	Shell("rm -r " + hostsFile)
	}
	_, err = Shell(command)
	return err
}

//开始执行发布任务
func (task *Task) Start(args string) (err error) {
	err = task.GitPull()
	if err == nil {
		err = task.DockerBuild()
		if err != nil { return err }
		err = task.DockerRun(args)
	}
	return err
}

//执行shell名
func Shell(s string) (string, error) {
	logger.Debugf("执行命令 %s", s)
	cmd := exec.Command("/bin/bash", "-c", s)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		logger.Debug(fmt.Sprintf("执行命令:%s 发送错误: %s", s, err))
	}
	return out.String(), err
}


func Init(){
	Shell("mkdir -p " + DefaultConfig.Home)
}

/**
 * 判断文件是否存在  存在返回 true 不存在返回false
 */
func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

